package com.cc.wechat.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cc.wechat.common.constants.ContactConstants;
import com.cc.wechat.dto.request.AddFriendRequest;
import com.cc.wechat.dto.request.HandleFriendRequest;
import com.cc.wechat.dto.response.FriendResponse;
import com.cc.wechat.entity.Contact;
import com.cc.wechat.entity.User;
import com.cc.wechat.mapper.ContactMapper;
import com.cc.wechat.mq.producer.MessageProducer;
import com.cc.wechat.service.ContactService;
import com.cc.wechat.service.UserService;
import com.cc.wechat.websocket.message.WebSocketMessage;
import com.cc.wechat.websocket.message.WebSocketMessageType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.cc.wechat.common.ResultCode;
import com.cc.wechat.exception.BusinessException;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 好友关系服务实现类
 */
@Service
@RequiredArgsConstructor
public class ContactServiceImpl extends ServiceImpl<ContactMapper, Contact> implements ContactService {

    private final UserService userService;
    private final MessageProducer messageProducer;

    /**
     * 发送好友请求
     * @param request 好友请求
     */
    @Override
    @Transactional
    public void sendFriendRequest(AddFriendRequest request) {
        // 1. 获取当前用户
        User currentUser = userService.getCurrentUser();
        Long currentUserId = currentUser.getId();

        // 2. 参数校验
        if (Objects.equals(currentUserId, request.getFriendId())) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, ContactConstants.Message.CANNOT_ADD_SELF);
        }

        // 3. 检查目标用户是否存在
        User friend = userService.getById(request.getFriendId());
        if (friend == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND, ContactConstants.Message.USER_NOT_FOUND);
        }

        // 4. 检查是否已经是好友
        Contact existingContact = lambdaQuery()
                .eq(Contact::getUserId, currentUserId)
                .eq(Contact::getFriendId, request.getFriendId())
                .one();

        if (existingContact != null) {
            if (existingContact.getStatus().equals(ContactConstants.Status.ACCEPTED)) {
                throw new BusinessException(ResultCode.FRIEND_ALREADY_EXISTS, ContactConstants.Message.ALREADY_FRIENDS);
            }
            if (existingContact.getStatus().equals(ContactConstants.Status.PENDING)) {
                throw new BusinessException(ResultCode.FRIEND_REQUEST_ALREADY_SENT,
                        ContactConstants.Message.FRIEND_REQUEST_ALREADY_SENT);
            }
        }

        // 5. 创建好友请求
        Contact contact = new Contact();
        contact.setUserId(currentUserId);
        contact.setFriendId(request.getFriendId());
        contact.setStatus(ContactConstants.Status.PENDING);
        contact.setRemark(request.getRemark());
        save(contact);

        
        // 6. 构建好友请求响应对象
        FriendResponse friendResponse = FriendResponse.builder()
                .id(contact.getId())
                .userId(currentUser.getId())
                .username(currentUser.getUsername())
                .nickname(currentUser.getNickname())
                .avatar(currentUser.getAvatar())
                .remark(contact.getRemark())
                .status(contact.getStatus())
                .createdAt(contact.getCreatedAt())
                .build();
        
        // 7. 构建WebSocket消息对象
        WebSocketMessage<FriendResponse> message = WebSocketMessage.<FriendResponse>builder()
                .type(WebSocketMessageType.FRIEND_REQ)  // 设置消息类型为好友请求
                .senderId(currentUserId)  // 设置发送者ID
                .receiverId(request.getFriendId())  // 设置接收者ID
                .data(friendResponse)  // 设置消息数据
                .timestamp(System.currentTimeMillis())  // 设置消息时间戳
                .build();

        // 8. 通过消息生产者发送WebSocket消息
        messageProducer.sendFriendRequest(message);
    }
    
    /**
     * 获取收到的好友请求
     * @return 好友请求列表
     */
    @Override
    public List<FriendResponse> getReceivedFriendRequests() {
        // 1. 获取当前用户
        User currentUser = userService.getCurrentUser();

        // 2. 查询收到的好友请求（所有状态）
        List<Contact> requests = lambdaQuery()
                .eq(Contact::getFriendId, currentUser.getId())
                .orderByDesc(Contact::getCreatedAt)  // 按创建时间倒序排序
                .list();

        // 3. 转换为Response
        return requests.stream()
                .map(contact -> {
                    User sender = userService.getById(contact.getUserId());
                    return FriendResponse.builder()
                            .id(contact.getId())
                            .userId(sender.getId())
                            .username(sender.getUsername())
                            .nickname(sender.getNickname())
                            .avatar(sender.getAvatar())
                            .remark(contact.getRemark())
                            .status(contact.getStatus())
                            .createdAt(contact.getCreatedAt())
                            .build();
                })
                .collect(Collectors.toList());
    }

    /**
     * 获取发送的好友请求
     * @return 好友请求列表
     */
    @Override
    public List<FriendResponse> getSentFriendRequests() {
        // 1. 获取当前用户
        User currentUser = userService.getCurrentUser();

        // 2. 查询发送的好友请求
        List<Contact> requests = lambdaQuery()
                .eq(Contact::getUserId, currentUser.getId())
                .eq(Contact::getStatus, ContactConstants.Status.PENDING)
                .list();

        // 3. 转换为Response
        return requests.stream()
                .map(contact -> {
                    User receiver = userService.getById(contact.getFriendId());
                    return FriendResponse.builder()
                            .id(contact.getId())
                            .userId(receiver.getId())
                            .username(receiver.getUsername())
                            .nickname(receiver.getNickname())
                            .avatar(receiver.getAvatar())
                            .remark(contact.getRemark())
                            .status(contact.getStatus())
                            .createdAt(contact.getCreatedAt())
                            .build();
                })
                .collect(Collectors.toList());
    }

    /**
     * 处理好友请求
     * @param requestId 好友请求ID
     * @param request 处理请求
     */
    @Override
    @Transactional
    public void handleFriendRequest(Long requestId, HandleFriendRequest request) {
        // 1. 获取当前用户
        User currentUser = userService.getCurrentUser();

        // 2. 查询好友请求
        Contact contact = getById(requestId);
        if (contact == null || !contact.getFriendId().equals(currentUser.getId())) {
            throw new BusinessException(ResultCode.FRIEND_REQUEST_NOT_FOUND, ContactConstants.Message.FRIEND_REQUEST_NOT_FOUND);
        }

        // 3. 检查请求状态
        if (!contact.getStatus().equals(ContactConstants.Status.PENDING)) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, "该好友请求已处理");
        }

        // 4. 更新请求状态
        contact.setStatus(request.getStatus());
        updateById(contact);

        // 5. 如果接受请求，创建双向好友关系
        if (request.getStatus().equals(ContactConstants.Status.ACCEPTED)) {
            Contact reverseContact = new Contact();
            reverseContact.setUserId(contact.getFriendId());
            reverseContact.setFriendId(contact.getUserId());
            reverseContact.setStatus(ContactConstants.Status.ACCEPTED);
            save(reverseContact);
        }

        // 6. 发送WebSocket消息通知原请求发送者
        FriendResponse friendResponse = FriendResponse.builder()
                .id(contact.getId())
                .userId(currentUser.getId())
                .username(currentUser.getUsername())
                .nickname(currentUser.getNickname())
                .avatar(currentUser.getAvatar())
                .remark(contact.getRemark())
                .status(contact.getStatus())
                .createdAt(contact.getCreatedAt())
                .build();

        WebSocketMessage<FriendResponse> message = WebSocketMessage.<FriendResponse>builder()
                .type(WebSocketMessageType.FRIEND_RES)
                .senderId(currentUser.getId())
                .receiverId(contact.getUserId())
                .data(friendResponse)
                .timestamp(System.currentTimeMillis())
                .build();

        messageProducer.sendFriendResponse(message);
    }

    /**
     * 获取好友列表
     * @return 好友列表
     */
    @Override
    public List<FriendResponse> getFriendList() {
        // 1. 获取当前用户
        User currentUser = userService.getCurrentUser();

        // 2. 查询好友列表
        List<Contact> friends = lambdaQuery()
                .eq(Contact::getUserId, currentUser.getId())
                .eq(Contact::getStatus, ContactConstants.Status.ACCEPTED)
                .list();

        // 3. 转换为Response
        return friends.stream()
                .map(contact -> {
                    User friend = userService.getById(contact.getFriendId());
                    return FriendResponse.builder()
                            .id(contact.getId())
                            .userId(friend.getId())
                            .username(friend.getUsername())
                            .nickname(friend.getNickname())
                            .avatar(friend.getAvatar())
                            .remark(contact.getRemark())
                            .status(contact.getStatus())
                            .createdAt(contact.getCreatedAt())
                            .build();
                })
                .collect(Collectors.toList());
    }

    /**
     * 删除好友
     * @param friendId 好友ID
     */
    @Override
    @Transactional
    public void deleteFriend(Long friendId) {
        // 1. 获取当前用户
        User currentUser = userService.getCurrentUser();
        Long currentUserId = currentUser.getId();

        // 2. 预检查好友关系是否存在
        Contact contact = lambdaQuery()
                .eq(Contact::getUserId, currentUserId)
                .eq(Contact::getFriendId, friendId)
                .eq(Contact::getStatus, ContactConstants.Status.ACCEPTED)
                .one();

        if (contact == null) {
            throw new BusinessException(ResultCode.FRIEND_NOT_EXISTS, ContactConstants.Message.FRIEND_NOT_EXISTS);
        }

        // 3. 删除双向好友关系
        boolean removed = lambdaUpdate()
                .eq(Contact::getStatus, ContactConstants.Status.ACCEPTED)
                .and(wrapper -> wrapper
                        .or(w -> w
                                .eq(Contact::getUserId, currentUserId)
                                .eq(Contact::getFriendId, friendId))
                        .or(w -> w
                                .eq(Contact::getUserId, friendId)
                                .eq(Contact::getFriendId, currentUserId)))
                .remove();

        if (!removed) {
            throw new BusinessException(ResultCode.OPERATION_FAILED, ContactConstants.Message.DELETE_FRIEND_FAILED);
        }
    }

    /**
     * 更新好友备注
     * @param friendId 好友ID
     * @param remark 新的备注
     */
    @Override
    @Transactional
    public void updateRemark(Long friendId, String remark) {
        // 1. 获取当前用户
        User currentUser = userService.getCurrentUser();
        Long currentUserId = currentUser.getId();

        // 2. 检查是否为好友关系
        Contact contact = lambdaQuery()
                .eq(Contact::getUserId, currentUserId)
                .eq(Contact::getFriendId, friendId)
                .eq(Contact::getStatus, ContactConstants.Status.ACCEPTED)
                .one();

        if (contact == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED, ContactConstants.Message.UPDATE_REMARK_FAILED);
        }

        // 3. 更新备注
        contact.setRemark(remark);
        updateById(contact);
    }
} 